package com.online.pay.web.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.online.pay.common.bean.ali.AliPayReqParams;
import com.online.pay.common.http.HttpClient;
import com.online.pay.common.modle.AliPayMethodEnum;
import com.online.pay.common.modle.Contains;
import com.online.pay.common.modle.TradeResult;
import com.online.pay.common.sign.AlipaySignature;
import com.online.pay.common.sign.KeyValueUtil;
import com.online.pay.common.utils.DateUtil;
import com.online.pay.common.utils.JsonUtil;
import com.online.pay.common.utils.ValidationResult;
import com.online.pay.common.utils.ValidationUtils;
import com.online.pay.common.utils.XmlJson;
import com.online.pay.common.utils.XmlUtils;
import com.online.pay.web.dao.entity.OrderInfo;
import com.online.pay.web.service.AliService;
import com.online.pay.web.service.OrderInfoService;

@Service
public class AliServiceImpl implements AliService {

	public static final Logger logger = LoggerFactory.getLogger(AliServiceImpl.class);
	
	@Value("${aliPay.serverUrl}")
	private String serverUrl;
	@Value("${aliPay.appId}")
	private String appId;
	@Value("${aliPay.privateKey}")
	private String privateKey;
	@Value("${aliPay.alipayPublicKey}")
	private String publicKey;
	@Autowired
	private HttpClient httpClient;
	@Autowired
	private OrderInfoService orderInfoService;

	@Override
	public TradeResult createOrder(AliPayReqParams aliPayReqParams) throws Exception {
		return createOrder(aliPayReqParams, null);
	}

	@Override
	public TradeResult createOrder(AliPayReqParams aliPayReqParams, String notityUrl) throws Exception {
		ValidationResult result = ValidationUtils.validateEntity(aliPayReqParams);
		if (result.isHasErrors()) {
			logger.error("创建订单参照验证错误", result.getErrorMsg().toString());
			throw new RuntimeException(result.getErrorMsg().toString());
		}
		TradeResult tradeResult = new TradeResult();
		String bizJson = JsonUtil.fromBeanToJson(aliPayReqParams);
		aliPayReqParams.setBiz_content(bizJson);
		aliPayReqParams.setApp_id(appId);
		aliPayReqParams.setCharset(Contains.CHARSET);
		aliPayReqParams.setFormat("json");
		aliPayReqParams.setVersion("1.0");
		aliPayReqParams.setMethod(AliPayMethodEnum.alipay_trade_precreate.getMethod());
		aliPayReqParams.setSign_type(Contains.ALI_SIGN_TYPE);
		aliPayReqParams.setTimestamp(DateUtil.toDate(new Date()));
		if (StringUtils.isNotBlank(notityUrl)) {
			aliPayReqParams.setNotify_url(notityUrl);
		}
		
		//转换map签名
		Map<String, String> reqMap = transBean2Map(aliPayReqParams);
		String respJson = httpClient.postMap(serverUrl,reqMap);
		logger.info("支付宝响应报文：" + respJson);
		
		if (respJson != null && StringUtils.isNotBlank(respJson)) {
			String respXml = XmlJson.json2xml(respJson);
			//验签
//			boolean isValid = AlipaySignature.rsaCheckV1(XmlUtils.xmlStrToMap(respXml), publicKey);
//			if (!isValid) {
//				throw new RuntimeException("验签失败！");
//			}
			String code = XmlUtils.getNodeValueFromXml("<code>", "</code>", respXml);
			String msg = XmlUtils.getNodeValueFromXml("<msg>", "</msg>", respXml);
			String qrCode = XmlUtils.getNodeValueFromXml("<qr_code>", "</qr_code>", respXml);
			if (Contains.SUCCESS.equals(code)) {
				tradeResult.setCode(code);
				tradeResult.setDesc(msg);;
				tradeResult.setQrCode(qrCode);
			}
			OrderInfo orderInfo = new OrderInfo();
			orderInfo.setResultcode(code);
			orderInfo.setResultdesc(msg);
			orderInfo.setUpdateDate(new Date());
			int count = orderInfoService.updateByPrimaryKeySelective(orderInfo);
			if (count != 1) {
				throw new RuntimeException("更新失败！");
			}
		}
		return tradeResult;
	}

	private Map<String, String> transBean2Map(AliPayReqParams aliPayReqParams) {
		Map<String, String> newMap = new HashMap<>();
		newMap.put("app_id", aliPayReqParams.getApp_id());
		newMap.put("method", aliPayReqParams.getMethod());
		newMap.put("format", aliPayReqParams.getFormat());
		newMap.put("charset", aliPayReqParams.getCharset());
		newMap.put("sign_type", aliPayReqParams.getSign_type());
		newMap.put("timestamp", aliPayReqParams.getTimestamp());
		newMap.put("notify_url", aliPayReqParams.getNotify_url());
		newMap.put("biz_content", aliPayReqParams.getBiz_content());
		String signValue = AlipaySignature.rsaSign(KeyValueUtil.mapToString(newMap),privateKey);
		newMap.put("sign", signValue);
		return newMap;
	}

}
